#include <assert.h>
#include <imbus.h>
#include <stdio.h>
#include <unistd.h>
#include "im_internals.h"

#define NO_TEST_OBJECT_MAIN
#include "test_object.h"
#include "test_object.c"

int main (int argc, char *argv [])
{
    IMConnection *conn;
    IMIOChannel  *in;
    IMIOChannel  *out;
    IMStream     *stream;
    IMBool        send = TRUE;
    IMInt         timeout = -1;
    IMInt         timeout_tmp = -1;
    IMIOError     error;
    IMPointer     obj;
    IMType        type;

    im_init(&argc, &argv);

    (void) TYPE_POINT;
    (void) TYPE_CIRCLE;

#if IM_ENABLE_DEBUG
    _im_slice_print_debug_info();
#endif

    if (argc <= 1) {
        printf ("Usage: test-connection [-s|-r] [timeout]\n"
                "  -s Read text stream input from stdin\n"
                "     and send all objects to stdout via\n"
                "     IMChannel\n"
                "  -r Read objects from stdin via IMChannel\n"
                "     and write them to stdout by text stream.\n");
        return 1;
    }

    if (strcmp (argv[1], "-s") == 0)
        send = TRUE;
    else
        send = FALSE;

    if (argc > 2)
        timeout = strtol(argv[2], 0, 10);

    stream = im_text_stream_new ();
    in  = im_io_channel_unix_new (0);
    out = im_io_channel_unix_new (1);

    if (send) {
        timeout_tmp = timeout;
        conn = im_connection_new (out);
        if (!im_stream_read (stream, in, &timeout_tmp, &error)) {
            fprintf (stderr, "Failed to read text stream.\n");
            return 1;
        }
        while (1) {
            timeout_tmp = timeout;
            type = im_stream_get_data_type (stream);
            if (type == IM_TYPE_INVALID)
                break;
            if (IM_TYPE_IS_OBJECT(type)) {
                obj = im_object_new (type);
                if (im_stream_get_object (stream, obj)) {
                    if (!im_connection_send (conn, obj, &timeout_tmp, &error)) {
                        fprintf (stderr, "Failed to send object. %d - %d\n", error,timeout_tmp);
                    }
                }
                im_object_unref (obj);
                sleep (1);
            } else {
                im_stream_skip_data (stream);
            }
        }
    } else {
        conn = im_connection_new (in);
        while (1) {
            timeout_tmp = timeout;
            obj = im_connection_next (conn, &timeout_tmp, &error);
            if (!obj) {
                fprintf (stderr, "Failed to read object. %d, remained timeout: %d\n", error, timeout_tmp);
                break;
            }
            timeout_tmp = timeout;
            im_stream_put_object (stream, obj);
            if (!im_stream_write (stream, out, &timeout_tmp, &error)) {
                fprintf (stderr, "Failed to write text stream. %d, remained timeout: %d\n", error, timeout_tmp);
            } else {
                fprintf (stderr, "Wrote a %s object.\n", im_type_get_name (im_object_get_type (obj)));
            }
            im_stream_clear (stream);
            im_object_unref (obj);
        }
    }

    im_object_unref(conn);
    im_object_unref(in);
    im_object_unref(out);
    im_object_unref(stream);

#if IM_ENABLE_DEBUG
    _im_slice_print_debug_info();
#endif

    return 0;
}
/*
vi:ts=4:nowrap:ai:expandtab
*/
